from decimal import Decimal
from django.db import transaction
from django_redis import get_redis_connection
from rest_framework import serializers
from goods.models import SKU
from orders.models import OrderInfo, OrderGoods
from datetime import datetime


class OrderShowSerializer(serializers.ModelSerializer):

    count = serializers.IntegerField(min_value=1,read_only=True)
    class Meta:
        model = SKU
        fields = '__all__'

class OrderSerializer(serializers.Serializer):

    freight = serializers.DecimalField(max_digits=10,decimal_places=2)
    skus = OrderShowSerializer(many=True)

class OrderSaveSerializer(serializers.ModelSerializer):

    class Meta:
        model = OrderInfo
        fields = ('order_id','address','pay_method')
        read_only_fields = ('order_id',)
        extra_kwags = {
            'address':{
                'write_only':True,
                'required' :True
            },
            'pay_method':{
                'write_only':True,
                'required':True
            }
        }

    def create(self, validated_data):
        '''
        1.获取用户,地址,支付方式
        3.生成订单号
        4.初始化生成订单基本信息表
        5.查询选中状态的sku--id对应的sku的商品
        6.遍历所有sku商品
        7.获取当前sku商品原始库存和销量
        8.判断购买数量是否大于库存
        9.不大于则修改sku中商品的库存和销量
        10.修改spu表中的总销量
        11.修改订单基本信息表中的总量和总价
        12.保存订单商品表
        13.删除缓存中选中的商品
        14.返回结果
        :param validated_data:
        :return:
        '''
        user = self.context['request'].user
        address = validated_data['address']
        pay_method = validated_data['pay_method']
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + '%09d'%user.id

        with transaction.atomic():
            save_point = transaction.savepoint()

            try:
                order = OrderInfo.objects.create(
                    order_id=order_id,
                    user = user,
                    address = address,
                    total_count = 0,
                    total_amount = Decimal(0),
                    freight = Decimal(10),
                    pay_method = pay_method,
                    status = OrderInfo.ORDER_STATUS_ENUM['UNSEND'] if pay_method == OrderInfo.PAY_METHODS_ENUM['CASH'] else
                    OrderInfo.ORDER_STATUS_ENUM['UNPAID'] )

                conn = get_redis_connection('cart')
                skus = conn.smembers('cart_select_%s'%user.id)
                sku_dict = {}
                for sku in skus:
                    sku_dict[int(sku)] = int(conn.hget('cart_%s'%user.id,sku))
                for sku_id,sku_count in sku_dict.items():
                    while True:
                        o_sku = SKU.objects.get(id=sku_id)
                        old_stock = o_sku.stock
                        old_sales = o_sku.sales
                        if o_sku.stock < sku_count:
                            raise serializers.ValidationError('库存不足')
                        new_stock = old_stock - sku_count
                        new_sales = old_sales + sku_count
                        # o_sku.stock -= sku_count
                        # o_sku.sales += sku_count
                        ret = SKU.objects.filter(id=sku_id,stock=old_stock).update(stock=new_stock,sales=new_sales)
                        if ret == 0:
                            continue
                        # o_sku.save()
                        o_sku.goods.sales += sku_count
                        o_sku.goods.save()
                        order.total_count += sku_count
                        order.total_amount += o_sku.price*sku_count

                        OrderGoods.objects.create(
                            order = order,
                            sku = o_sku,
                            count = sku_count,
                            price = o_sku.price
                        )
                        break

                order.total_amount += order.freight
                order.save()
            except:
                transaction.savepoint_rollback(save_point)

            else:
                transaction.savepoint_commit(save_point)
                for sku in skus:
                    conn.hdel('cart_%s'%user.id,sku)
                    conn.srem('cart_select_%s'%user.id,sku)

                return order


class OrderSKUSerializer(serializers.ModelSerializer):

    class Meta:
        model = SKU
        fields = '__all__'


class OrderGoodsSerializer(serializers.ModelSerializer):

    # create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True, required=False)
    sku = OrderSKUSerializer()

    class Meta:
        model = OrderGoods
        fields = '__all__'

class OrderListSerializer(serializers.ModelSerializer):

    # status = serializers.IntegerField(min_value=1,max_value=1,read_only=True)
    #
    # pay_method = serializers.IntegerField(min_value=1,max_value=1,read_only=True)

    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True, required=False)

    skus = OrderGoodsSerializer(many=True)
    # print (skus)
    class Meta:
        model = OrderInfo
        fields = '__all__'



class UpdateCommentSerializer(serializers.ModelSerializer):

    class Meta:
        model = OrderGoods
        fields = ('order','sku','comment','score','is_anonymous')

    def validate(self, attrs):
        comment = attrs['comment']

        if len(comment) < 5:
            raise serializers.ValidationError({'message':'评论不能小于5个字段'})

        return attrs

    def update(self, instance, validated_data):

        # sku = validated_data['sku']
        # orders = validated_data['order']
        comment = validated_data['comment']
        score = validated_data['score']
        is_anonymous = validated_data['is_anonymous']
        # order = instance[0]
        instance.comment = comment
        instance.score = score
        instance.is_anonymous = is_anonymous
        instance.is_commented = True
        instance.save()
        instance.sku.comments += 1
        instance.sku.save()
        instance.sku.goods.comments += 1
        instance.sku.goods.save()
        # orderinfo = OrderInfo.objects.filter(order_id=orders.order_id)[0]
        ordergoods = OrderGoods.objects.filter(order=instance.order_id)
        ret = 0
        for order in ordergoods:
            if not order.is_commented:
                ret += 1
        if ret == 0:
            # orderinfo.status = 5
            # orderinfo.save()
            instance.order.status = 5
            instance.order.save()

        return instance










